# -*- utf-8 -*-
import platform
import random
import re

from django.core.cache import cache
from django.http import FileResponse
from django.template import loader

from utils.config import OutTime


def set_kwargs(obj, **kwargs):
    for k, v in kwargs.items():
        setattr(obj, k, v)


def verify_mobile(phone):
    ret = re.match(r"1[358]\d{9}", str(phone))
    return ret is not None


def get_ver_code(redis_key):
    code = random.randint(100000, 999999)
    # 五分钟失效
    # cache.set(redis_key, code, 60 * 5)
    cache.set(redis_key, code, OutTime.SMS_VER_CODE_OUT_TIME)
    return code


def get_reset_code(redis_key):
    code = random.randint(100000, 999999)
    # 五分钟失效
    cache.set(redis_key, code, OutTime.RESET_CODE_OUT_TIME)
    return code


def user_create_email_html(code):
    """获取发送注册账号的邮件html"""
    html_source = loader.get_template('email/create_user_email.html')
    text = html_source.render({'code': code})
    return text


def sqlalchemy_to_dict(result, column_names):
    if isinstance(result, list) or isinstance(result, tuple):
        ret = []

        for i in result:
            item = {}
            for ind, k in enumerate(i):
                item[column_names[ind]] = k
            ret.append(item)
        return ret
    else:
        ret = {}
        for ind, k in enumerate(result):
            ret[column_names[ind]] = k
        return ret


def datetime_format(dt_obj, format_='%Y-%m-%d %H:%M:%S'):
    return dt_obj.strftime(format_)


def isdev(args1, args2):
    if platform.system() == 'Linux':
        return args2
    else:
        return args1


def csv_generate(df, filename, sep):
    """
    生成csv
    :param dict_data:
    :param filename:
    :param sep:
    :return:
    """
    import io
    stream = io.StringIO()
    df.to_csv(stream, encoding='utf8', sep=sep, index=False)
    response = FileResponse(stream.getvalue())
    stream.close()
    response['content-type'] = "application/octet-stream"
    response['content-disposition'] = 'attachment;filename="{}"'.format(filename)
    return response


def filter_symbol(cr, op, eq):
    if op == "=" or op == "==":
        return cr == eq
    elif op == "!=":
        return cr != eq
    elif op == ">":
        return cr > eq
    elif op == "<":
        return cr < eq
    elif op == ">=":
        return cr >= eq
    elif op == "<=":
        return cr <= eq
    elif op == "LIKE":
        return cr.like(f"%{eq}%")
    elif op == "like":
        return cr.like(f"%{eq}%")
    elif op == "not like":
        return cr.notlike(eq)
    elif op == "IS NULL":
        return cr is None
    elif op == "IS NOT NULL":
        return cr is not None
    elif op == "is null":
        return cr is None
    elif op == "is not null":
        return cr is not None
    else:
        return cr.like(f"%{eq}%")


def rand_name(length=10, has_num=True, has_letter=True, has_symbol=False):
    """
    随机生成名字
    :param length:长度
    :param has_num:是否包含数字
    :param has_letter:是否包含字母
    :param has_symbol:是否包含符号
    :return:
    """
    letter_list = []
    ret = ''
    if has_num:
        letter_list.extend(list('0123456789'))
    if has_letter:
        letter_list.extend(list('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'))
    if has_symbol:
        letter_list.extend(list('~!@#$%^&*()_+=-'))
    if letter_list:
        for i in range(length):
            ret += letter_list[random.randint(0, len(letter_list) - 1)]

    return ret


def str_of_num(num):
    """
    递归实现，精确为最大单位值 + 小数点后三位
    """

    def strofsize(num, level):
        if level >= 2:
            return num, level
        elif num >= 10000:
            num /= 10000
            level += 1
            return strofsize(num, level)
        else:
            return num, level

    units = ['', '万', '亿']
    num, level = strofsize(num, 0)
    if level > len(units):
        level -= 1
    return '{}{}'.format(round(num, 3), units[level])


def find_pojo(_type):
    if _type.__name__ == 'Pojo':
        return True
    elif _type.__name__ != 'Object':
        find_pojo(_type.__class__)
    else:
        return False
